package com.landinfo.web.rest.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Configuration
public class HttpRequestUtil {


    @Autowired
    private RestTemplateBuilder builder;

    @Bean
    public RestTemplate restTemplate() {
        return builder.build();
    }

    public String getHttpRequest(String url,HttpMethod httpMethod) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        String strbody = restTemplate().exchange(url, httpMethod, entity, String.class).getBody();
        return strbody;
    }

    public String postHttpRequest(String url, JSONObject map, JSONObject headerObj) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("msg", "head msg test");
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        if (headerObj != null) {
            Object[] keys = headerObj.keySet().toArray();
            for (Object o : keys) {
                String key = o.toString();
                headers.add(key, headerObj.getString(key));
            }
        }
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(map, headers);
        String result = restTemplate().postForObject(url, httpEntity, String.class);
        return result;
    }

    public static String sendPostDataByMap(String url, Map<String, Object> map, String encoding) throws Exception {
        String result = "";
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建post方式请求对象
        url = url.replaceAll(" ", "%20"); // 替换掉地址中的空格
        HttpPost httpPost = new HttpPost(url);
        // 装填参数
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
            }
        }
        // 设置参数到请求对象中
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, encoding));
        // 设置header信息
        // 指定报文头【Content-type】、【User-Agent】
        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
        httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 执行请求操作，并拿到结果（同步阻塞）
        CloseableHttpResponse response = httpClient.execute(httpPost);
        // 获取结果实体
        // 判断网络连接状态码是否正常(0--200都数正常)
        if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) {
            result = EntityUtils.toString(response.getEntity(), "utf-8");
        }
        // 释放链接
        response.close();
        return result;
    }

    public static JSONObject sendPostDataByJson(JSONObject obj) {
        JSONObject result = new JSONObject();
        result.put("success", false);
        if (obj.get("url") == null) {
            result.put("msg", "请求地址为空！");
            return result;
        }
        try {
            String res = "";
            String elasticSearchUri = "";
            // 创建httpclient对象
            CloseableHttpClient httpClient = HttpClients.createDefault();
            // 创建post方式请求对象
            HttpPost httpPost = new HttpPost(elasticSearchUri + obj.getString("url"));
            // 组装header
            if (obj.get("headers") != null) {
                JSONObject headerObj = obj.getJSONObject("headers");
                Object[] keys = headerObj.keySet().toArray();
                for (Object o : keys) {
                    String key = o.toString();
                    httpPost.addHeader(key, headerObj.getString(key));
                }
            }
            // 设置参数到请求对象中
            if (obj.get("json") != null) {
                StringEntity stringEntity = new StringEntity(JSON.toJSONString(obj.get("json")), ContentType.APPLICATION_JSON);
                stringEntity.setContentEncoding("utf-8");
                httpPost.setEntity(stringEntity);
            }
            // 执行请求操作，并拿到结果（同步阻塞）
            CloseableHttpResponse response = httpClient.execute(httpPost);
            // 获取结果实体
            // 判断网络连接状态码是否正常(0--200都数正常)
            int code = response.getStatusLine().getStatusCode();
            if (code == org.apache.http.HttpStatus.SC_OK) {
                res = EntityUtils.toString(response.getEntity(), "utf-8");
                result.replace("success", true);
            }
            // 释放链接
            response.close();
            result.put("code", code);
            result.put("data", res);
            return result;
        } catch (Exception e) {
            System.out.println("Post请求错误：" + e.getMessage());
            result.put("msg", "请求失败！" + e.getMessage());
            return result;
        }
    }

    public static String sendGetData(String url, String token) throws IOException {
        String result = "";
        // 创建httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建get方式请求对象
        url = url.replaceAll(" ", "%20"); // 替换掉地址中的空格
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Content-type", "application/json");
        if (token != null && !token.equals("")) {
            httpGet.addHeader("token", token);
        }
        // 通过请求对象获取响应对象
        CloseableHttpResponse response = httpClient.execute(httpGet);
        // 获取结果实体
        // 判断网络连接状态码是否正常(0--200都数正常)
        if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) {
            result = EntityUtils.toString(response.getEntity(), "utf-8");
        }
        // 释放链接
        response.close();
        return result;
    }


    public static JSONObject sendNoSLLGet(String url, JSONObject headers) {
        JSONObject result = new JSONObject();
        result.put("success", false);
        if (url == null || url.equals("")) {
            result.put("msg", "请求地址为空！");
            return result;
        }
        try {
            String res = "";
            // 绕过证书验证
            SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
            RequestConfig config = RequestConfig.custom().setConnectTimeout(50000).setSocketTimeout(50000).build();
            // 创建httpclient对象
            CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
            // 创建get方式请求对象
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("Content-type", "application/json");
            // 组装header
            if (headers != null) {
                Object[] keys = headers.keySet().toArray();
                for (Object o : keys) {
                    String key = o.toString();
                    httpGet.addHeader(key, headers.getString(key));
                }
            }
            // 通过请求对象获取响应对象
            CloseableHttpResponse response = httpClient.execute(httpGet);
            // 获取结果实体
            // 判断网络连接状态码是否正常(0--200都数正常)
            int code = response.getStatusLine().getStatusCode();
            if (code == org.apache.http.HttpStatus.SC_OK) {
                res = EntityUtils.toString(response.getEntity(), "utf-8");
                result.replace("success", true);
            }
            // 释放链接
            response.close();
            result.put("code", code);
            result.put("data", res);
            return result;
        } catch (Exception e) {
            System.out.println("Get请求错误：" + e.getMessage());
            result.put("msg", "请求失败！" + e.getMessage());
            return result;
        }
    }

    public static Boolean checkParamValid(String value) {
        value = value.toLowerCase();
        return !value.contains("select ") && !value.contains("select(")
            && !value.contains("create ") && !value.contains("create(")
            && !value.contains("update ") && !value.contains("update(")
            && !value.contains("delete ") && !value.contains("delete(")
            && !value.contains("insert ") && !value.contains("insert(")
            && !value.contains(" and ") && !value.contains(")and") && !value.contains("and(")
            && !value.contains(" or ") && !value.contains(")or") && !value.contains("or(");
    }

    public static String setSlashAndBackSlash(String pathStr){
        if(File.separator.equals("\\")){
            if(pathStr.contains("/")){
                pathStr = pathStr.replaceAll("/", "\\\\");
            }
        }else if(File.separator.equals("/")){
            if(pathStr.contains("\\")){
                pathStr = pathStr.replaceAll("\\\\", "/");
            }
        }
        return pathStr;
    }
}
